package angry.courses.servlets;

import angry.courses.database.ICoursesDB;

import angry.courses.database.DuplicateRegNrException;

import java.util.List;
import java.util.ArrayList;
import java.util.Arrays;

import java.io.IOException;
import java.io.PrintWriter;

import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

public class RegisterServlet extends HttpServlet {
    private ICoursesDB coursesDB;

    public void init() throws ServletException {
	coursesDB = (ICoursesDB) getServletContext().getAttribute("coursesDB");
    }

    public void destroy() {
	coursesDB = null;
    }

    public void doGet(HttpServletRequest req, HttpServletResponse res) 
	throws ServletException, IOException {
	
	res.setContentType("text/html");
	PrintWriter out = res.getWriter();
	out.println(new HtmlFormatter() {

	    public void script(StringBuffer buf) {
		buf.append("<script language=\"javascript\">\n");
		buf.append("<!--\n");
		buf.append("function validSelection(select)\n");
		buf.append("{\n");
		buf.append(" var nrselections = 0;\n");
		buf.append(" for (var i = 0; i < select.options.length; i++)\n");
		buf.append(" {\n");
		buf.append("  if (select.options[i].selected)\n");
		buf.append("  nrselections++;\n");
		buf.append(" }\n");
		buf.append(" return nrselections <= 4;\n");
		buf.append("}\n");

		buf.append("function validateForm()\n");
		buf.append("{\n");
		buf.append(" if (validSelection(document.forms[0].courses1)\n");
		buf.append("&& validSelection(document.forms[0].courses2))\n");
		buf.append(" {\n");
		buf.append("  document.forms[0].submit();\n");
		buf.append(" }\n");
		buf.append("else\n");
		buf.append(" {\n");
		buf.append("  var warningSpan =\n");
		buf.append("    document.getElementById('warning')\n");
		buf.append("  warningSpan.style.color = \"#CC0000\";\n");
		buf.append("  return false;\n");
		buf.append(" }\n");
		buf.append("}\n");

		buf.append("// -->\n");
		buf.append("</script>\n");
	    }

	    public String title() {
		return "Register";
	    }

	    public void body(StringBuffer buf) {
		buf.append(heading(3, "Register"));
		buf.append("<form method=\"post\" action=\"Register\" >");
		buf.append("<table>");
		buf.append("<tr>");
		buf.append("<th>Enter your credentials:</th>");
		buf.append("<th colspan=\"2\">Select your courses:</th>");
		buf.append("</tr>");
		buf.append("<tr>");
		buf.append(th("") + th("Semester I") + th("Semester II"));
		buf.append("</tr>");
		buf.append("<tr valign=\"top\" >");
		buf.append("<td>" + credentialsForm() + "</td>");
		buf.append("<td>" + courseForm(1) + "</td>");
		buf.append("<td>" + courseForm(2) + "</td>");
		buf.append("</tr>");
		buf.append("<tr>");
		buf.append("<td></td>");
		buf.append("<td colspan=\"2\" align=\"center\">");
		buf.append("<font size=\"-1\">");
		buf.append("Hold CTRL and click to select multiple courses.");
		buf.append("<br><span id=\"warning\">");
		buf.append("Select at most 4 courses per semester.");
		buf.append("</span></font></td>");
		buf.append("</tr>");
		buf.append("</table>");
		buf.append("<input type=\"button\" value=\"Submit\"");
		buf.append("OnClick=\"validateForm()\" />");
		buf.append("</form>");
	    }

	    public String credentialsForm() {
		StringBuffer buf = new StringBuffer();
		buf.append("<table>");
		buf.append(tr("Name: ", textbox("name"))); 
		buf.append(tr("Reg. Nr.: ", textbox("regnr")));
		buf.append(tr("Year: ", dropdown("year", "",
						 "1", "2", "3", "4")));
		buf.append("</table>");
		return buf.toString();
	    }

	    public String courseForm(int sem) {
		List<String> courseNames = coursesDB.getCourseNames(sem);
		return multiple("courses" + sem, courseNames.size(),
				new ArrayList<String>(), courseNames);
	    }
	}.htmlTag());
	out.close();
    }

    public void doPost(HttpServletRequest req, HttpServletResponse res)
	throws ServletException, IOException {
	final String name = req.getParameter("name");
	final String regnr = req.getParameter("regnr");
	final int year = Integer.parseInt(req.getParameter("year"));

	String[] selection1 = req.getParameterValues("courses1");
	String[] selection2 = req.getParameterValues("courses2");

	final List<String> allCourses = new ArrayList<String>();
	if (selection1 != null)
	    allCourses.addAll(Arrays.asList(selection1));
	if (selection2 != null)
	    allCourses.addAll(Arrays.asList(selection2));

	res.setContentType("text/html");
	PrintWriter out = res.getWriter();

	try {
	    coursesDB.register(name, regnr, year, allCourses);
	    out.println(new HtmlFormatter() {
		public String title() {
		    return "Registered";
		}

		public void body(StringBuffer buf) {
		    buf.append(heading(3, "Registered"));
		    buf.append("<b>" + name + "</b>");
		    buf.append(", your registration is complete.<br>");
		    buf.append("Click " + link("here", "index.html"));
		    buf.append(" to go back.");
		}
	    }.htmlTag());
	} catch (DuplicateRegNrException e) {
	    out.println(new HtmlFormatter() {
		public String title() {
		    return "Registration failed";
		}

		public void body(StringBuffer buf) {
		    buf.append(heading(3, "Registration failed"));
		    buf.append("<b>" + name + "</b>");
		    buf.append(", the registration number ");
		    buf.append("<b>" + regnr + "</b>");
		    buf.append(" has already been registered.<br>");
		    buf.append("Click " + link("here", "index.html"));
		    buf.append(" to go back.");
		}
	    }.htmlTag());
	} finally {
	    out.close();
	}
    }
}